#pragma once

#include <iostream>
#include <string>
#include <list>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Mutex.hpp"

using namespace LogMudule;
// 观察者模式
class UserInterface
{
public:
    virtual ~UserInterface() = default;
    virtual void SendTo(int sockfd,const std::string &message) = 0;
    virtual bool operator== (const InetAddr &u) = 0;
    virtual std::string Id() = 0;
};


// 用户
class User : public UserInterface
{
public:
    User(const InetAddr &id)
    :_id(id)
    {}
    void SendTo(int sockfd,const std::string &message) override
    {
        LOG(LogLevel::INFO) << "send message to " << _id.Addr() << " info: " << message;
        int n = ::sendto(sockfd,message.c_str(),message.size(),0,_id.NetAddr(),_id.NetAddrLen());
    }
    ~User()
    {}
    bool operator== (const InetAddr &u) override
    {
        return _id == u;
    }
    std::string Id()
    {
        return _id.Addr();
    }
private:
    InetAddr _id;
};



// 对用户消息进行路由
// 把所有的用户先管理起来
class UserManger
{
public:
    UserManger(){}
    void PrintUser()
    {
        for(auto &user : _online_user)
        {
            LOG(LogLevel::DEBUG) << "在线用户" <<user->Id();
        }
        if(_online_user.empty())
        {
            LOG(LogLevel::DEBUG) << "没有在线用户";
        }
    }

    void AddUser(InetAddr &id)
    {
        // 去重
        LockGuard lockguard(_mutex);
        for(auto &user : _online_user)
        {
            if(*user == id)
            {
                LOG(LogLevel::INFO) << id.Addr() << "用户存在";
                return;
            }
            LOG(LogLevel::INFO) << id.Addr() << "用户新增";
        }
        _online_user.push_back(std::make_shared<User>(id));
    }

    void DelUser(InetAddr &id)
    {
        LockGuard lockguard(_mutex);    
        for(auto it = _online_user.begin();it != _online_user.end();++it)
        {
            if(*(*it) == id)
            {
                _online_user.erase(it);
                LOG(LogLevel::INFO) << id.Addr() << "用户删除";
                break;
            }
        }
        PrintUser();
    }

    void Router(int sockfd , const std::string &message)
    {
        LockGuard lockguard(_mutex);
        for(auto &user : _online_user)
        {
            user->SendTo(sockfd,message);
        }
    }



    ~UserManger(){}
private:
    std::list<std::shared_ptr<UserInterface>> _online_user;
    Mutex _mutex;
};